{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Concentration Prior Type Analysis of Variation Bayesian Gaussian Mixture\n\n\nThis example plots the ellipsoids obtained from a toy dataset (mixture of three\nGaussians) fitted by the ``BayesianGaussianMixture`` class models with a\nDirichlet distribution prior\n(``weight_concentration_prior_type='dirichlet_distribution'``) and a Dirichlet\nprocess prior (``weight_concentration_prior_type='dirichlet_process'``). On\neach figure, we plot the results for three different values of the weight\nconcentration prior.\n\nThe ``BayesianGaussianMixture`` class can adapt its number of mixture\ncomponents automatically. The parameter ``weight_concentration_prior`` has a\ndirect link with the resulting number of components with non-zero weights.\nSpecifying a low value for the concentration prior will make the model put most\nof the weight on few components set the remaining components weights very close\nto zero. High values of the concentration prior will allow a larger number of\ncomponents to be active in the mixture.\n\nThe Dirichlet process prior allows to define an infinite number of components\nand automatically selects the correct number of components: it activates a\ncomponent only if it is necessary.\n\nOn the contrary the classical finite mixture model with a Dirichlet\ndistribution prior will favor more uniformly weighted components and therefore\ntends to divide natural clusters into unnecessary sub-components.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Author: Thierry Guillemot <thierry.guillemot.work@gmail.com>\n# License: BSD 3 clause\n\nimport numpy as np\nimport matplotlib as mpl\nimport matplotlib.pyplot as plt\nimport matplotlib.gridspec as gridspec\n\nfrom sklearn.mixture import BayesianGaussianMixture\n\nprint(__doc__)\n\n\ndef plot_ellipses(ax, weights, means, covars):\n    for n in range(means.shape[0]):\n        eig_vals, eig_vecs = np.linalg.eigh(covars[n])\n        unit_eig_vec = eig_vecs[0] / np.linalg.norm(eig_vecs[0])\n        angle = np.arctan2(unit_eig_vec[1], unit_eig_vec[0])\n        # Ellipse needs degrees\n        angle = 180 * angle / np.pi\n        # eigenvector normalization\n        eig_vals = 2 * np.sqrt(2) * np.sqrt(eig_vals)\n        ell = mpl.patches.Ellipse(means[n], eig_vals[0], eig_vals[1],\n                                  180 + angle, edgecolor='black')\n        ell.set_clip_box(ax.bbox)\n        ell.set_alpha(weights[n])\n        ell.set_facecolor('#56B4E9')\n        ax.add_artist(ell)\n\n\ndef plot_results(ax1, ax2, estimator, X, y, title, plot_title=False):\n    ax1.set_title(title)\n    ax1.scatter(X[:, 0], X[:, 1], s=5, marker='o', color=colors[y], alpha=0.8)\n    ax1.set_xlim(-2., 2.)\n    ax1.set_ylim(-3., 3.)\n    ax1.set_xticks(())\n    ax1.set_yticks(())\n    plot_ellipses(ax1, estimator.weights_, estimator.means_,\n                  estimator.covariances_)\n\n    ax2.get_xaxis().set_tick_params(direction='out')\n    ax2.yaxis.grid(True, alpha=0.7)\n    for k, w in enumerate(estimator.weights_):\n        ax2.bar(k, w, width=0.9, color='#56B4E9', zorder=3,\n                align='center', edgecolor='black')\n        ax2.text(k, w + 0.007, \"%.1f%%\" % (w * 100.),\n                 horizontalalignment='center')\n    ax2.set_xlim(-.6, 2 * n_components - .4)\n    ax2.set_ylim(0., 1.1)\n    ax2.tick_params(axis='y', which='both', left=False,\n                    right=False, labelleft=False)\n    ax2.tick_params(axis='x', which='both', top=False)\n\n    if plot_title:\n        ax1.set_ylabel('Estimated Mixtures')\n        ax2.set_ylabel('Weight of each component')\n\n# Parameters of the dataset\nrandom_state, n_components, n_features = 2, 3, 2\ncolors = np.array(['#0072B2', '#F0E442', '#D55E00'])\n\ncovars = np.array([[[.7, .0], [.0, .1]],\n                   [[.5, .0], [.0, .1]],\n                   [[.5, .0], [.0, .1]]])\nsamples = np.array([200, 500, 200])\nmeans = np.array([[.0, -.70],\n                  [.0, .0],\n                  [.0, .70]])\n\n# mean_precision_prior= 0.8 to minimize the influence of the prior\nestimators = [\n    (\"Finite mixture with a Dirichlet distribution\\nprior and \"\n     r\"$\\gamma_0=$\", BayesianGaussianMixture(\n        weight_concentration_prior_type=\"dirichlet_distribution\",\n        n_components=2 * n_components, reg_covar=0, init_params='random',\n        max_iter=1500, mean_precision_prior=.8,\n        random_state=random_state), [0.001, 1, 1000]),\n    (\"Infinite mixture with a Dirichlet process\\n prior and\" r\"$\\gamma_0=$\",\n     BayesianGaussianMixture(\n        weight_concentration_prior_type=\"dirichlet_process\",\n        n_components=2 * n_components, reg_covar=0, init_params='random',\n        max_iter=1500, mean_precision_prior=.8,\n        random_state=random_state), [1, 1000, 100000])]\n\n# Generate data\nrng = np.random.RandomState(random_state)\nX = np.vstack([\n    rng.multivariate_normal(means[j], covars[j], samples[j])\n    for j in range(n_components)])\ny = np.concatenate([np.full(samples[j], j, dtype=int)\n                    for j in range(n_components)])\n\n# Plot results in two different figures\nfor (title, estimator, concentrations_prior) in estimators:\n    plt.figure(figsize=(4.7 * 3, 8))\n    plt.subplots_adjust(bottom=.04, top=0.90, hspace=.05, wspace=.05,\n                        left=.03, right=.99)\n\n    gs = gridspec.GridSpec(3, len(concentrations_prior))\n    for k, concentration in enumerate(concentrations_prior):\n        estimator.weight_concentration_prior = concentration\n        estimator.fit(X)\n        plot_results(plt.subplot(gs[0:2, k]), plt.subplot(gs[2, k]), estimator,\n                     X, y, r\"%s$%.1e$\" % (title, concentration),\n                     plot_title=k == 0)\n\nplt.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.6.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}